#include "EditorNodeScalePropertyModel.h"

#include "Object/NewObject.h"
#include "Scene/SceneNode.h"

TSharedObjectPtr<REditorNodeScalePropertyModel> REditorNodeScalePropertyModel::Create(
    TSharedObjectPtr<RSceneNode> InNode,
    RObject* InParent
    )
{
    TSharedObjectPtr<REditorNodeScalePropertyModel> NewModel = NewObject<REditorNodeScalePropertyModel>(InParent);
    NewModel->Node = InNode;

    return NewModel;
}

float REditorNodeScalePropertyModel::GetX() const
{
    return Node->GetScale().X;
}

void REditorNodeScalePropertyModel::SetX(float InX)
{
    SVec3 NewScale = Node->GetScale();
    NewScale.X = InX;
    Node->SetScale(NewScale);
}

float REditorNodeScalePropertyModel::GetY() const
{
    return Node->GetScale().Y;
}

void REditorNodeScalePropertyModel::SetY(float InY)
{
    SVec3 NewScale = Node->GetScale();
    NewScale.Y = InY;
    Node->SetScale(NewScale);
}

float REditorNodeScalePropertyModel::GetZ() const
{
    return Node->GetScale().Z;
}

void REditorNodeScalePropertyModel::SetZ(float InZ)
{
    SVec3 NewScale = Node->GetScale();
    NewScale.Z = InZ;
    Node->SetScale(NewScale);
}

void REditorNodeScalePropertyOperation::ChangeValue(TSharedObjectPtr<RSceneNode> InNode, EAxis InAxis, float InOldValue, float InValue)
{
    Node = InNode;
    Axis = InAxis;
    OldValue = InOldValue;
    NewValue = InValue;

    RedoFunction.Bind([this](TSharedObjectPtr<REditorPageModel>)
    {
        switch (Axis)
        {
            case EAxis::X:
            {
                SVec3 Position=Node->GetScale();
                Position.X=NewValue;
                Node->SetScale(Position);
                break;
            }    
            case EAxis::Y:
            {
                SVec3 Position=Node->GetScale();
                Position.Y=NewValue;
                Node->SetScale(Position);
                break;
            }
            case EAxis::Z:
            {
                SVec3 Position=Node->GetScale();
                Position.Z=NewValue;
                Node->SetScale(Position);
                break;
            }
        }
    });

    UndoFunction.Bind([this](TSharedObjectPtr<REditorPageModel> )
    {
        switch (Axis)
        {
            case EAxis::X:
            {
                SVec3 Position=Node->GetScale();
                Position.X=OldValue;
                Node->SetScale(Position);
                break;
            }    
            case EAxis::Y:
            {
                SVec3 Position=Node->GetScale();
                Position.Y=OldValue;
                Node->SetScale(Position);
                break;
            }
            case EAxis::Z:
            {
                SVec3 Position=Node->GetScale();
                Position.Z=OldValue;
                Node->SetScale(Position);
                break;
            }
        }
    });

    MergeFunction.Bind([this](TSharedObjectPtr<REditorPageOperation> Operation)
    {
        if(!Operation->IsA<REditorNodeScalePropertyOperation>())
        {
            return false;
        }
        TSharedObjectPtr<REditorNodeScalePropertyOperation> 
            FormerOperation=Operation;
        
        if(FormerOperation->Node!=Node
            || FormerOperation->Axis!=Axis)
        {
            return false;
        }

        if(FormerOperation->OldValue==NewValue)
        {
            return false;
        }

        FormerOperation->NewValue=NewValue;
        return true;

    });

}
